package com.jhhc.StormSurgeForecast.AstronomicalTide.ServiceImpl;


import com.jhhc.FloodForecast.Sensor.Dao.BDMS_ST_SENSORALARM_BMapper;
import com.jhhc.FloodForecast.Sensor.Pojo.BDMS_ST_SENSORALARM_B;
import com.jhhc.FloodForecast.Sensor.Pojo.BDMS_ST_STBPRP_B;
import com.jhhc.FloodForecast.Sensor.Service.BDMS_ST_STBPRP_BService;
import com.jhhc.StormSurgeForecast.StormSurge.Dao.BDMS_ST_ASTROTD_FMapper;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Pojo.BDMS_ST_ASTROTD_F;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Pojo.DataBO.*;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Service.BDMS_ST_ASTROTD_FService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Util.TimeUtil;
import com.jhhc.StormSurgeForecast.StormSurge.Pojo.FBC.BDMS_FBC_ASTROTD_A;
import com.jhhc.StormSurgeForecast.StormSurge.Service.BDMS_FBC_ASTROTD_AService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class BDMS_ST_ASTROTD_FServiceImpl implements BDMS_ST_ASTROTD_FService {

    @Value("${datasourceType}")
    String datasourceType;
    @Value("${departments}")
    String department;
    @Resource
    private BDMS_ST_ASTROTD_FMapper bdms_st_astrotd_fMapper;

    @Resource
    private BDMS_ST_SENSORALARM_BMapper bdmsStSensoralarmBMapper;

    @Resource(name = "BDMS_ST_STBPRP_BService")
    private BDMS_ST_STBPRP_BService stStbprpBService;

    @Resource(name = "BDMS_FBC_ASTROTD_AService")
    private BDMS_FBC_ASTROTD_AService bdmsFbcAstrotdAService;

    @Override
    public List<BDMS_ST_ASTROTD_F> selectTide(String StationCode, String StartTime, String EndTime, int departmentId) {
        return bdms_st_astrotd_fMapper.selectTide(StationCode,StartTime,EndTime,departmentId);
    }

    @Override
    public List<BDMS_ST_ASTROTD_F> selectFTDZ(List<String> StationCodes, String StartTime, String EndTime, int departmentId) {
        return bdms_st_astrotd_fMapper.selectFTDZ(StationCodes, StartTime, EndTime, departmentId);
    }

    @Override
    public List<BDMS_ST_ASTROTD_F> selectByOnwFtdz(List<String> StationCode, String StartTime, String EndTime, int departmentId) {
        return bdms_st_astrotd_fMapper.selectByOnwFtdz(StationCode, StartTime, EndTime, departmentId);
    }

    @Override
    public List<BDMS_ST_ASTROTD_F> selectNewEstData(List<String> stcd) {
        return bdms_st_astrotd_fMapper.selectNewEstData(stcd);
    }

    @Override
    public List<BDMS_ST_ASTROTD_F> selectNewOne(String stcd) {
        return bdms_st_astrotd_fMapper.selectNewOne(stcd);
    }

    @Override
    public int insertBatch(List<BDMS_ST_ASTROTD_F> entities) {
        int num = 0;//insert插入总数量
        int count = 0;//insert插入数量
        int batchCount = 300;//每批commit的个数
        int batchLastIndex = batchCount - 1;// 每批最后一个的下标
        if ("mysql".equals(datasourceType)){
            for (int index = 0; index < entities.size() -1;) {
                if(batchLastIndex > entities.size() - 1){
                    batchLastIndex = entities.size() - 1;
                    count = bdms_st_astrotd_fMapper.insertBatch(entities.subList(index,batchLastIndex + 1));
                    num+=count;
                    break;
                }else {
                    count = bdms_st_astrotd_fMapper.insertBatch(entities.subList(index,batchLastIndex + 1));
                    index = batchLastIndex + 1;
                    batchLastIndex = index + (batchCount - 1);
                }
                num+=count;
            }
            return num;
        }else if ("sqlserver".equals(datasourceType)){
            for (int index = 0; index < entities.size() -1;) {
                if(batchLastIndex > entities.size() - 1){
                    batchLastIndex = entities.size() - 1;
                    count = bdms_st_astrotd_fMapper.insertBatchSqlServer(entities.subList(index,batchLastIndex + 1));
                    num+=count;
                    break;
                }else {
                    count = bdms_st_astrotd_fMapper.insertBatchSqlServer(entities.subList(index,batchLastIndex + 1));
                    index = batchLastIndex + 1;
                    batchLastIndex = index + (batchCount - 1);
                }
                num+=count;
            }
            return num;
        }else {
            return -1;
        }
    }

    @Override
    public int delete(int year, List<String> stationCodes) {
        return bdms_st_astrotd_fMapper.delete(year,stationCodes);
    }

    @Override
    public int insertBatchWz(String startTime, String endTime) {
        List<BDMS_ST_STBPRP_B> bList = stStbprpBService.selectByCity();
        if (bList != null && bList.size() > 0) {
            List<BDMS_ST_ASTROTD_F> entities = new ArrayList<>();
            BDMS_ST_ASTROTD_F astrotd = null;
            for (BDMS_ST_STBPRP_B stStbprpB : bList) {
                List<BDMS_FBC_ASTROTD_A> astrotds = bdmsFbcAstrotdAService.selectByGrid(2205,startTime,endTime, Integer.valueOf(stStbprpB.getGrids()));
                double d = 0.0;
                for (int i = 0; i < astrotds.size(); i++) {
                    astrotd = new BDMS_ST_ASTROTD_F();
                    astrotd.setStcd(stStbprpB.getStcd());
                    astrotd.setYmdh(astrotds.get(i).getTm());
                    if ("-990000000".equals(astrotds.get(i).getDtvalues())) {
                        astrotd.setFtdz(d);
                    }else {
                        astrotd.setFtdz(Double.parseDouble(astrotds.get(i).getDtvalues()));
                    }
                    astrotd.setHltdmk(0);
                    astrotd.setUnitname(0);
                    d = astrotd.getFtdz();
                    entities.add(astrotd);
                }
            }
            //先删后入
            bdms_st_astrotd_fMapper.deleteWz(startTime, endTime, bList.stream().filter(Objects::nonNull).
                    map(BDMS_ST_STBPRP_B::getStcd).collect(Collectors.toList()));
            return insertBatch(entities);
        }else {
            return 0;
        }
    }

    @Override
    public int wenZhouDataHandle(int year) {
        List<String> stcd = Arrays.asList("70800001","70800002","70800003","70800004","70800005","70800006","70800007",
                "70800008","70800009","70800010");
        List<BDMS_ST_ASTROTD_F> astrotds = bdms_st_astrotd_fMapper.getTwcTideByYear(String.valueOf(year), stcd, "0");
        Map<String, List<BDMS_ST_ASTROTD_F>> stcdMap = astrotds.stream().filter(Objects::nonNull).
                collect(Collectors.groupingBy(BDMS_ST_ASTROTD_F::getStcd));
        for (Map.Entry<String, List<BDMS_ST_ASTROTD_F>> entry : stcdMap.entrySet()) {
            double d = entry.getValue().get(0).getFtdz();
            for (int i = 0; i < entry.getValue().size(); i++) {
                if (entry.getValue().get(i).getFtdz() < -1000) {
                    entry.getValue().get(i).setFtdz(d);
                }
                if (entry.getValue().get(i).getFtdz() == -99999) {
                    entry.getValue().get(i).setFtdz(d);
                }
                d = entry.getValue().get(i).getFtdz();
            }
            bdms_st_astrotd_fMapper.delete(year, Collections.singletonList(entry.getKey()));
            bdms_st_astrotd_fMapper.insertBatch(entry.getValue());
        }
        return 0;
    }

    @Override
    public List<Departments> getDepartments() {
        List<String> integers = bdms_st_astrotd_fMapper.getDepartments();
        if (integers != null && integers.size() > 0) {
            List<Departments> departmentsList = new ArrayList<>();
            Departments departments = null;
            for (String string : integers) {
                departments = new Departments();
                if (Objects.equals(string, "0")) {
                    departments.setDepartmentName("河海大学");
                } else if (Objects.equals(string, "1")) {
                    departments.setDepartmentName("北京师范大学珠海校区");
                } else if (Objects.equals(string, "4")) {
                    departments.setDepartmentName("系统预报");
                }
                departments.setDepartmentId(string);
                departmentsList.add(departments);
            }
//            for (String string : integers) {
//                departments = new Departments();
//                if (Objects.equals(string, "0")) {
//                    departments.setDepartmentName("河海大学");
//                }
//                departments.setDepartmentId(string);
//                departmentsList.add(departments);
//            }
            return departmentsList;
        }else {
            return null;
        }
    }
    /**
     *获取选定时间段内逐时天文潮
     */
    @Override
    public List<AstronomictTide> getHourlyTwcTide(String startTime, String endTime, List<String> stationCodes,
                                                  String departmentId, boolean getHLTide,int projectId) {
        List<BDMS_ST_ASTROTD_F> fList = bdms_st_astrotd_fMapper.getHourlyTwcTide(startTime, endTime,
                stationCodes, departmentId, getHLTide);
        List<BDMS_ST_SENSORALARM_B> bdms_st_sensoralarm_bs = bdmsStSensoralarmBMapper
                .selectByStcd(stationCodes, "TDZ", projectId);
        if (fList != null && fList.size() > 0) {
            TimeUtil timeUtil = new TimeUtil();
            List<BDMS_ST_ASTROTD_F> codes;
            List<AstronomictTide> astronomictTides = new ArrayList<>();
            AstronomictTide astronomictTide = null;
            for (String code : stationCodes) {
                codes = fList.stream().filter(x -> x.getStcd().equals(code)).collect(Collectors.toList());
                if (codes.size() > 0) {
                    List<AstronomictTideInfo> astronomictTideInfos = new ArrayList<>();
                    AstronomictTideInfo astronomictTideInfo = null;
                    astronomictTide = new AstronomictTide();
                    astronomictTide.setStationCode(code);
                    astronomictTide.setSubTitle(startTime + "--" + endTime);
                    astronomictTide.setAxisX(timeUtil.formatting(codes.get(codes.size() - 1).getYmdh()) + "," +
                            timeUtil.formatting(codes.get(0).getYmdh()));
                    for (int i = 0; i < 1; i++) {
                        AstronomictTideTime a = bdms_st_astrotd_fMapper.selectMaxAndMinTime(code);
                        astronomictTideInfo = new AstronomictTideInfo();
                        if (a != null) {
                            astronomictTideInfo.setStartTime(timeUtil.formatting(a.getEndTime()));
                            astronomictTideInfo.setEndTime(timeUtil.formatting(a.getStartTime()));
                        }
                        astronomictTideInfo.setValueName("天文潮");
                        astronomictTideInfo.setSenserType("twc");
                        astronomictTideInfo.setUnit("m");
                        List<AstronomictTideData> astronomictTideDatas = new ArrayList<>();
                        AstronomictTideData astronomictTideData = null;
                        AstronomictTideData astronomictTideDataMax = new AstronomictTideData();
                        AstronomictTideData astronomictTideDataMin = new AstronomictTideData();
                        double max = 0;
                        double min = codes.get(0).getFtdz();
                        for (BDMS_ST_ASTROTD_F bdmsStAstrotdF : codes) {
                            astronomictTideData = new AstronomictTideData();
                            astronomictTideData.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                            if (bdmsStAstrotdF.getFtdz() != null) {
                                astronomictTideData.setTdz(String.format("%.2f",bdmsStAstrotdF.getFtdz()));
                                if (bdmsStAstrotdF.getFtdz() > max) {
                                    max = bdmsStAstrotdF.getFtdz();
                                    astronomictTideDataMax.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                                    astronomictTideDataMax.setTdz(String.format("%.2f",max));
                                }
                                if (bdmsStAstrotdF.getFtdz() < min) {
                                    min = bdmsStAstrotdF.getFtdz();
                                    astronomictTideDataMin.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                                    astronomictTideDataMin.setTdz(String.format("%.2f",min));
                                }
                            }
                            if (bdmsStAstrotdF.getHltdmk() != null) {
                                astronomictTideData.setHltdmk(String.valueOf(bdmsStAstrotdF.getHltdmk()));
                            }
                            astronomictTideDatas.add(astronomictTideData);
                        }
                        if (bdms_st_sensoralarm_bs != null && bdms_st_sensoralarm_bs.size() > 0) {
                            BDMS_ST_SENSORALARM_B bdms_st_sensoralarm_b = bdms_st_sensoralarm_bs.
                                    stream().filter(x -> x.getStcd().equals(code)).findAny().orElse(null);
                            if (bdms_st_sensoralarm_b != null) {
                                astronomictTide.setAlarmTideData(bdms_st_sensoralarm_b.getAlarmvalue());
                            }
                        }
                        astronomictTideInfo.setDatas(astronomictTideDatas);
                        astronomictTideInfo.setMaxData(astronomictTideDataMax);
                        astronomictTideInfo.setMinData(astronomictTideDataMin);
                        astronomictTideInfo.setRemark("hltdmk值说明：1日高高潮，2日低高潮，3日高低潮，4日低低潮");
                        astronomictTideInfos.add(astronomictTideInfo);
                        astronomictTideData = null;
                    }
                    astronomictTide.setBaseDatas(astronomictTideInfos);
                    astronomictTideInfo = null;
                    astronomictTides.add(astronomictTide);
                }
            }
            astronomictTide = null;
            codes = null;
            return astronomictTides;
        }else {
            return null;
        }
    }

    /**
     *获取选定时间段内天文高低潮
     */
    @Override
    public List<AstronomictTide> getHLTwcTide(String startTime, String endTime, List<String> stationCodes,
                                              String departmentId,int projectId) {
        List<BDMS_ST_ASTROTD_F> fList = bdms_st_astrotd_fMapper.getHLTwcTide(startTime, endTime,
                stationCodes, departmentId);
        List<BDMS_ST_SENSORALARM_B> bdms_st_sensoralarm_bs = bdmsStSensoralarmBMapper
                .selectByStcd(stationCodes, "TDZ", projectId);
        if (fList != null && fList.size() > 0) {
            TimeUtil timeUtil = new TimeUtil();
            List<BDMS_ST_ASTROTD_F> codes = null;
            List<AstronomictTide> astronomictTides = new ArrayList<>();
            AstronomictTide astronomictTide = null;
            for (String code : stationCodes) {
                codes = fList.stream().filter(x -> x.getStcd().equals(code)).collect(Collectors.toList());
                if (codes.size() > 0) {
                    List<AstronomictTideInfo> astronomictTideInfos = new ArrayList<>();
                    AstronomictTideInfo astronomictTideInfo = null;
                    astronomictTide = new AstronomictTide();
                    astronomictTide.setStationCode(code);
                    astronomictTide.setSubTitle(startTime + "--" + endTime);
                    astronomictTide.setAxisX(timeUtil.formatting(codes.get(codes.size() - 1).getYmdh()) + "," +
                            timeUtil.formatting(codes.get(0).getYmdh()));
                    for (int i = 0; i < 1; i++) {
                        AstronomictTideTime a = bdms_st_astrotd_fMapper.selectMaxAndMinTime(code);
                        astronomictTideInfo = new AstronomictTideInfo();
                        if (a != null) {
                            astronomictTideInfo.setStartTime(timeUtil.formatting(a.getEndTime()));
                            astronomictTideInfo.setEndTime(timeUtil.formatting(a.getStartTime()));
                        }
                        astronomictTideInfo.setValueName("天文高低潮");
                        astronomictTideInfo.setSenserType("twc");
                        astronomictTideInfo.setUnit("m");
                        List<AstronomictTideData> astronomictTideDatas = new ArrayList<>();
                        AstronomictTideData astronomictTideData = null;
                        AstronomictTideData astronomictTideDataMax = new AstronomictTideData();
                        AstronomictTideData astronomictTideDataMin = new AstronomictTideData();
                        double max = 0;
                        double min = codes.get(0).getFtdz();
                        for (BDMS_ST_ASTROTD_F bdmsStAstrotdF : codes) {
                            astronomictTideData = new AstronomictTideData();
                            astronomictTideData.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                            if (bdmsStAstrotdF.getFtdz() != null) {
                                astronomictTideData.setTdz(String.format("%.2f",bdmsStAstrotdF.getFtdz()));
                                if (bdmsStAstrotdF.getFtdz() > max) {
                                    max = bdmsStAstrotdF.getFtdz();
                                    astronomictTideDataMax.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                                    astronomictTideDataMax.setTdz(String.format("%.2f",max));
                                }
                                if (bdmsStAstrotdF.getFtdz() < min) {
                                    min = bdmsStAstrotdF.getFtdz();
                                    astronomictTideDataMin.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                                    astronomictTideDataMin.setTdz(String.format("%.2f",min));
                                }
                            }
                            if (bdmsStAstrotdF.getHltdmk() != null) {
                                astronomictTideData.setHltdmk(String.valueOf(bdmsStAstrotdF.getHltdmk()));
                            }
                            astronomictTideDatas.add(astronomictTideData);
                        }
                        if (bdms_st_sensoralarm_bs != null && bdms_st_sensoralarm_bs.size() > 0) {
                            BDMS_ST_SENSORALARM_B bdms_st_sensoralarm_b = bdms_st_sensoralarm_bs.
                                    stream().filter(x -> x.getStcd().equals(code)).findAny().orElse(null);
                            if (bdms_st_sensoralarm_b != null) {
                                astronomictTide.setAlarmTideData(bdms_st_sensoralarm_b.getAlarmvalue());
                            }
                        }
                        astronomictTideInfo.setDatas(astronomictTideDatas);
                        astronomictTideInfo.setMaxData(astronomictTideDataMax);
                        astronomictTideInfo.setMinData(astronomictTideDataMin);
                        astronomictTideInfo.setRemark("hltdmk值说明：1日高高潮，2日低高潮，3日高低潮，4日低低潮");
                        astronomictTideInfos.add(astronomictTideInfo);
                        astronomictTideData = null;
                    }
                    astronomictTide.setBaseDatas(astronomictTideInfos);
                    astronomictTideInfo = null;
                    astronomictTides.add(astronomictTide);
                }
            }
            astronomictTide = null;
            codes = null;
            return astronomictTides;
        }else {
            return null;
        }
    }

    @Override
    public List<AstronomictTide> getTwcTideByYear(String year, List<String> stationCodes,
                                                  String departmentId,int projectId) {
        List<BDMS_ST_ASTROTD_F> fList = bdms_st_astrotd_fMapper.getTwcTideByYear(year,stationCodes,departmentId);
        List<BDMS_ST_SENSORALARM_B> bdms_st_sensoralarm_bs = bdmsStSensoralarmBMapper
                .selectByStcd(stationCodes, "TDZ", projectId);
        if (fList != null && fList.size() > 0) {
            TimeUtil timeUtil = new TimeUtil();
            List<BDMS_ST_ASTROTD_F> codes = null;
            List<AstronomictTide> astronomictTides = new ArrayList<>();
            AstronomictTide astronomictTide = null;
            for (String code : stationCodes) {
                codes = fList.stream().filter(x -> x.getStcd().equals(code)).collect(Collectors.toList());
                if (codes.size() > 0) {
                    List<AstronomictTideInfo> astronomictTideInfos = new ArrayList<>();
                    AstronomictTideInfo astronomictTideInfo = null;
                    astronomictTide = new AstronomictTide();
                    astronomictTide.setStationCode(code);
                    astronomictTide.setSubTitle(year + "年");
                    astronomictTide.setAxisX(timeUtil.formatting(codes.get(codes.size() - 1).getYmdh()) + "," +
                            timeUtil.formatting(codes.get(0).getYmdh()));
                    for (int i = 0; i < 1; i++) {
                        AstronomictTideTime a = bdms_st_astrotd_fMapper.selectMaxAndMinTime(code);
                        astronomictTideInfo = new AstronomictTideInfo();
                        if (a != null) {
                            astronomictTideInfo.setStartTime(timeUtil.formatting(a.getEndTime()));
                            astronomictTideInfo.setEndTime(timeUtil.formatting(a.getStartTime()));
                        }
                        astronomictTideInfo.setValueName("天文高低潮");
                        astronomictTideInfo.setSenserType("twc");
                        astronomictTideInfo.setUnit("m");
                        List<AstronomictTideData> astronomictTideDatas = new ArrayList<>();
                        AstronomictTideData astronomictTideData = null;
                        AstronomictTideData astronomictTideDataMax = new AstronomictTideData();
                        AstronomictTideData astronomictTideDataMin = new AstronomictTideData();
                        double max = 0;
                        double min = codes.get(0).getFtdz();
                        for (BDMS_ST_ASTROTD_F bdmsStAstrotdF : codes) {
                            astronomictTideData = new AstronomictTideData();
                            astronomictTideData.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                            if (bdmsStAstrotdF.getFtdz() != null) {
                                astronomictTideData.setTdz(String.format("%.2f",bdmsStAstrotdF.getFtdz()));
                                if (bdmsStAstrotdF.getFtdz() > max) {
                                    max = bdmsStAstrotdF.getFtdz();
                                    astronomictTideDataMax.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                                    astronomictTideDataMax.setTdz(String.format("%.2f",max));
                                }
                                if (bdmsStAstrotdF.getFtdz() < min) {
                                    min = bdmsStAstrotdF.getFtdz();
                                    astronomictTideDataMin.setTm(timeUtil.formatting(bdmsStAstrotdF.getYmdh()));
                                    astronomictTideDataMin.setTdz(String.format("%.2f",min));
                                }
                            }
                            if (bdmsStAstrotdF.getHltdmk() != null) {
                                astronomictTideData.setHltdmk(String.valueOf(bdmsStAstrotdF.getHltdmk()));
                            }
                            astronomictTideDatas.add(astronomictTideData);
                        }
                        if (bdms_st_sensoralarm_bs != null && bdms_st_sensoralarm_bs.size() > 0) {
                            BDMS_ST_SENSORALARM_B bdms_st_sensoralarm_b = bdms_st_sensoralarm_bs.
                                    stream().filter(x -> x.getStcd().equals(code)).findAny().orElse(null);
                            if (bdms_st_sensoralarm_b != null) {
                                astronomictTide.setAlarmTideData(bdms_st_sensoralarm_b.getAlarmvalue());
                            }
                        }
                        astronomictTideInfo.setDatas(astronomictTideDatas);
                        astronomictTideInfo.setMaxData(astronomictTideDataMax);
                        astronomictTideInfo.setMinData(astronomictTideDataMin);
                        astronomictTideInfo.setRemark("hltdmk值说明：1日高高潮，2日低高潮，3日高低潮，4日低低潮");
                        astronomictTideInfos.add(astronomictTideInfo);
                        astronomictTideData = null;
                    }
                    astronomictTide.setBaseDatas(astronomictTideInfos);
                    astronomictTideInfo = null;
                    astronomictTides.add(astronomictTide);
                }
            }
            astronomictTide = null;
            codes = null;
            return astronomictTides;
        }else {
            return null;
        }
    }

    @Override
    public List<BDMS_ST_ASTROTD_F> tide_output(String startTime, String endTime) {
        return bdms_st_astrotd_fMapper.tide_output(startTime, endTime);

    }

}
